package com.hebeiboruan.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hebeiboruan.entity.DTO.system.VerifyDTO;
import com.hebeiboruan.example.verify.ExampleVerify;
import com.hebeiboruan.testsystem.entity.Example;
import com.hebeiboruan.example.mapper.ExampleMapper;
import com.hebeiboruan.example.service.ExampleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class ExampleServiceImpl extends  ServiceImpl<ExampleMapper, Example> implements ExampleService {
    private RestTemplate restTemplate;
    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    private void setVerify(ResponseEntity<String> response,Example example) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        if(response.getBody().replaceAll("\\s","").equals(example.getExampleResponse().replaceAll("\\s",""))){
            example.setExampleResult(1);    
            if(example.getExampleVerify()!=null){
                Class verifyClass=Class.forName(example.getExampleVerify());
                Constructor constructor = verifyClass.getDeclaredConstructor();
                ExampleVerify verify = (ExampleVerify) constructor.newInstance();
                VerifyDTO result = verify.run(restTemplate);
                if(!result.getResult()){
                    example.setExampleResult(2);
                    example.setExampleError(result.getError());
                }
            }
        }else {
            example.setExampleResult(2);
            example.setExampleError(response.getBody());
        }
    }

    @Override
    public void runExample(Example example)  {
        HttpHeaders httpHeaders=new HttpHeaders();
        if(example.getExampleHead()!=null){
            String[] heads = example.getExampleHead().split(",");
            for (int i=0;i<heads.length;i++){
                String[] args = heads[i].split(":");
                httpHeaders.set(args[0],args[1]);
            }
        }
        HttpEntity head=new HttpEntity(httpHeaders);

        String[] request=null;
        if(example.getExampleRequest()!=null){
            request = example.getExampleRequest().split(",");
        }
        ResponseEntity<String> response=null;
        switch (example.getExampleMethod()){
            case "get":
                StringBuffer requestBody=new StringBuffer();
                if(example.getExampleRequest()!=null){
                    for (int i=0;i<request.length;i++){
                        String[] args = request[i].split(":");
                        requestBody.append(args[0]).append("=").append(args[1]);
                        if(i!=request.length-1){
                            requestBody.append("&");
                        }
                    }
                   response = restTemplate.exchange(example.getExampleUrl()+ "?" + requestBody, HttpMethod.GET, head, String.class);

                    try{
                        setVerify(response,example);
                    }catch (Exception e){
                        throw new RuntimeException(e);
                    }
                }else{
                    response = restTemplate.exchange(example.getExampleUrl(), HttpMethod.GET, head, String.class);
                    try{
                        setVerify(response,example);
                    }catch (Exception e){
                        throw new RuntimeException(e);
                    }
                }

                break;
            case "post":
                Map requestBodyMap=new HashMap();
                if(example.getExampleRequest()!=null){
                    for (int i=0;i<request.length;i++){
                        String[] args = request[i].split(":");
                        requestBodyMap.put(args[0],args[1]);
                    }
                }
                 response = restTemplate.exchange(example.getExampleUrl(), HttpMethod.POST, head, String.class,requestBodyMap);
                try{
                    setVerify(response,example);
                }catch (Exception e){
                    throw new RuntimeException(e);
                }
                break;
        }
        example.setExampleDate(new Date());
        updateById(example);
    }

    @Override
    public void runFunction(Example example) {
        List<Example> exampleModel = list(new QueryWrapper<Example>().eq("example_model", example.getExampleNo()));
        AtomicReference<Integer> result= new AtomicReference<>(1);
        exampleModel.forEach(item->{
            runExample(item);
            if(!item.getExampleResult().equals(2)){
                result.set(2);
            }
        });
        example.setExampleResult(result.get());
        updateById(example);
    }

    @Override
    public void runModel(Example example) {
        List<Example> exampleModel = list(new QueryWrapper<Example>().eq("example_model", example.getExampleNo()));
        AtomicReference<Integer> result= new AtomicReference<>(1);
        exampleModel.forEach(item->{
            runFunction(item);
            if(!item.getExampleResult().equals(2)){
                result.set(2);
            }
        });
        example.setExampleResult(result.get());
        updateById(example);
    }
}

